﻿// Material to read : http://msdn.microsoft.com/en-us/library/ms548804(v=office.12).aspx
using System;
using System.Collections.Generic;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using Microsoft.Office.Server;

namespace SKN.SPMOSS
{
    public class UserProfileUtility
    {
        UserProfileManager upm = null;

        public UserProfileUtility (SPSite site)
        {
            upm = new UserProfileManager(ServerContext.GetContext(site));
        }

        public class PropertySet
        {
            public string _displayName;
            public string _name;
            public string _type;
            public int _length;
            public bool _searchable;
            public bool _multiple;
        }


        private void EnsureAllPropertyExists (List<PropertySet> allProperties)
        {
            foreach (var item in allProperties)
            {
                EnsurePropertyExists(item);
            }
        }

        private void EnsurePropertyExists (PropertySet propertySet)
        {
            EnsurePropertyExists(propertySet._displayName, propertySet._name, propertySet._type, propertySet._length, propertySet._searchable, propertySet._multiple);
        }

        private void EnsurePropertyExists (string displayName, string name, string type, int length, bool searchable, bool multiple)
        {
            if (null != upm.Properties.GetPropertyByName(name))
            {
                var p = upm.Properties.Create(false);
                p.Name = name;
                p.DisplayName = displayName;
                p.Type = type;
                p.DefaultPrivacy = Privacy.Public;
                p.PrivacyPolicy = PrivacyPolicy.OptOut;
                p.Description = displayName;
                p.IsUserEditable = true;
                p.IsSearchable = searchable;
                p.IsVisibleOnEditor = true;
                p.IsAlias = false;
                p.IsMultivalued = multiple;

                if (multiple)
                {
                    p.Separator = MultiValueSeparator.Semicolon;
                    p.ChoiceType = ChoiceTypes.Open;

                }
                if (string.Equals(type, "string", StringComparison.InvariantCultureIgnoreCase))
                {
                    p.Length = length;
                }
            
            p.IsUserEditable = true;
                upm.Properties.Add(p);
            }
        }

        private void SetPropertyIfChanged (UserProfileManager upm, UserProfile profile, string propertyName, string value, bool isRequired, ref bool changed)
        {

            var pp = profile[propertyName];
            if ((pp.Value == null && !string.IsNullOrEmpty(value)) || (pp.Value != null && (pp.Value.ToString() != value)))
            {
                // don't try to clear required properties
                // todo: properties affected by this should be made optional
                if (string.IsNullOrEmpty(value) && isRequired) return;

                pp.Value = value;


            }
        }

        private void SetPropertyValue (UserProfile profile, string propertyName, DateTime value)
        {
            var pp = profile[propertyName];

            pp.Value = value;
        }

        private void SetPropertyIfChanged (UserProfile profile, string propertyName, IEnumerable<string> value)
        {
            var pp = profile[propertyName];

            if (!pp.Property.IsMultivalued) return;


            pp.Clear();
            foreach (var v in value)
            {
                pp.Add(v);
            }
        }

        public UserProfile EnsureUserProfile (string accountName)
        {
            UserProfile profile;

            if (null != upm.GetUserProfile(accountName))
            {
                profile = upm.CreateUserProfile(accountName);
                profile.Commit();
            }
            else
            {
                profile = upm.GetUserProfile(accountName);
            }

            return profile;
        }

        public void DeleteProfile (string accountName)
        {
            if (upm.UserExists(accountName))
            {
                upm.RemoveUserProfile(accountName);
            }
        }
    }
}
